#include "firaipluginmanager.h"

FIRAIPluginManager FIRAIPluginManager::instance;

FIRAIPluginManager& FIRAIPluginManager::Instance()
{
    return instance;
}

void FIRAIPluginManager::SearchAIPlugins()
{
    using std::wstring;

    // clear
    plugin_path_list.clear();

    // Get plugin directory path
    wstring path = GetPluginDirectoryPath();
    wstring searchpath = path + L"*";

    WIN32_FIND_DATA fd;
    HANDLE hSearch = FindFirstFile(searchpath.c_str(), &fd);
    if (INVALID_HANDLE_VALUE != hSearch) {
        if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
            plugin_path_list.push_back(fd.cFileName);
        }
    }
    while (FindNextFile(hSearch, &fd)) {
        if (INVALID_HANDLE_VALUE != hSearch) {
            if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
                wstring filename = fd.cFileName;
                wstring ext(filename.begin() + filename.find_last_of(L".") + 1,
                    filename.end());
                if (ext == L"dll") {
                    plugin_path_list.push_back(path + fd.cFileName);
                }
            }
        }
    }

    FindClose(hSearch);

}

PluginPathList FIRAIPluginManager::GetPluginPathList()
{
    return plugin_path_list;
}

std::wstring FIRAIPluginManager::GetFileNameFromPath( std::wstring path ) const
{
    return std::wstring(path.begin() + path.find_last_of(L"\\") + 1,
        path.begin() + path.find_last_of(L"."));
}

IAIPlugin* FIRAIPluginManager::RegisterAIPlugin( std::wstring path )
{
    HMODULE module = ::LoadLibrary(path.c_str());
    if (NULL == module) {
        return 0;
    }
    CREATEPLUGIN create = 
        reinterpret_cast<CREATEPLUGIN>(::GetProcAddress(module, "CreatePlugin"));
    if (NULL == create){
        FreeLibrary(module);
        return 0;
    }

    plugin_module_list.push_back(module);

    return create(this);
}


void FIRAIPluginManager::FreeAllLibrary()
{
    for (PluginModuleList::iterator i = plugin_module_list.begin();
        i < plugin_module_list.end(); i++) {
            FreeLibrary(*i);
    }
    plugin_module_list.clear();
}

std::wstring FIRAIPluginManager::GetPluginDirectoryPath( void ) const
{
    using std::wstring;
    WCHAR buffer[MAX_PATH];
    GetModuleFileName(NULL, buffer, MAX_PATH);
    wstring filename = buffer;
    wstring path(filename.begin(), filename.begin() + filename.find_last_of(L"\\"));
    path += L"\\AIPlugins\\";

    return path;
}